#pragma once

#include "exports.hpp"
#include "pointer.hpp"




namespace Engine
{
	namespace Script
	{
		template class ENGINE_SCRIPT_API pointer<class Object>;




		/**
		 * This class serves as a base class for all classes that want to be registered
		 * with angelscript as reference types.
		 *
		 * It offers intrinsic reference counting, available casting functions, etc...
		 *
		 * On top of that, it offers the capabilities to reflect an object's properties at runtime.
		 */
		class ENGINE_SCRIPT_API Object
		{
		public:

			typedef pointer<Object>   ptr;

			Object();
			virtual ~Object();

			void AddRef();
			void Release();

			template <class A, class B>
			static B* refCast(A* a)
			{
				// If the handle is already a null handle, then just return the null handle
				if(!a)
					return NULL;

				// Now try to dynamically cast the pointer to the wanted type
				B* b = dynamic_cast<B*>(a);
				if(b != NULL)
				{
					// Since the cast was made, we need to increase the ref counter for the returned handle
					b->AddRef();
				}
				return b;
			}

		private:

			std::size_t   m_ref;
		};
		///////////////////////////////////////////////////////////////////////////////////////////
	}
	///////////////////////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////////////////////////
